from frog import Frog
from egg import Egg
from util import delete_eggs
import random
from PIL import Image, ImageDraw
import json
import os
import pygame


class Env:
    show_speed = 1
    # steps_per_round = 3000
    steps_per_round = 30
    delete_eggs = True

    def __init__(self, screen, clock) -> None:
        self.screen: pygame.Surface = screen
        self.clock: pygame.time.Clock = clock
        self.env_xsize = 300
        self.env_ysize = 300
        self.foods = [[0] * self.env_ysize] * self.env_xsize
        self.food_qty: int = 2000
        self.egg_qty: int = 80
        self.frogs: list[Frog] = []
        self.eggs: list[Egg] = []

        if Env.delete_eggs:
            print("唵缚悉波罗摩尼莎诃!")
            delete_eggs()

    def rebuild_frog_and_food(self):
        self.frogs.clear()

        for i in range(self.env_xsize):  # clear food
            for j in range(self.env_ysize):
                self.foods[i][j] = 0
        for i in range(len(self.eggs)):  # 1 egg build 4 frog
            for j in range(4):
                self.frogs.append(
                    Frog(
                        int(self.env_xsize / 2 + random.randint(1, 90)),
                        int(self.env_ysize / 2 + random.randint(1, 90)),
                        self.eggs[i],
                    )
                )
        print(f"created {4+len(self.eggs)} frogs")
        for i in range(self.food_qty):
            self.foods[random.randint(1, self.env_xsize - 3)][
                random.randint(1, self.env_ysize - 3)
            ] = 1

    def draw_food(self, screen: pygame.Surface):
        for x in range(self.env_xsize):
            for y in range(self.env_ysize):
                if self.foods[x][y] > 0:
                    # pygame.draw.circle(screen, "green", (x, y), 2, 1)
                    pygame.draw.circle(screen, "blue", (x, y), 1)

    def load_eggs(self):
        if not os.path.exists("eggs.json"):
            print("eggs.json not existed, create it now")
            for i in range(self.egg_qty):
                self.eggs.append(Egg.create_brand_new_egg())
                return
        with open("eggs.json", "r") as f:
            try:
                eggs_list = json.load(f)
                self.eggs = [Egg.from_dict(egg) for egg in eggs_list]
                print(f"loaded {len(self.eggs)} eggs from eggs.json")
            except Exception as e:
                print("load json error: ", e)
                
            if len(self.eggs) == 0:
                print("eggs.json is empty, create it now")
                for i in range(self.egg_qty):
                    self.eggs.append(Egg.create_brand_new_egg())
                

    def run(self):
        self.load_eggs()

        img = pygame.image.load("frog.png")

        running = True
        while running:
            self.rebuild_frog_and_food()
            all_dead = False
            # pygame.QUIT event means the user clicked X to close your window
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

            self.screen.fill("white")
            self.clock.tick(1)  # limits FPS

            for i in range(self.steps_per_round):
                if all_dead:
                    print("all frog dead, exit")
                    break
                all_dead = True
                for frog in self.frogs:
                    if frog.active(self):
                        all_dead = False
                    if frog.alive and frog.move_count == 0 and i > 100:
                        frog.alive = False
                if i % self.show_speed != 0:
                    continue

                for frog in self.frogs:
                    frog.show(img, self.screen)

                self.draw_food(self.screen)

                pygame.display.flip()
                
            self.lay_eggs()

    def lay_eggs(self):
        # self.frogs.sort()
        new_eggs = []
        for i in range(self.egg_qty):
            # for i in range(len(self.frogs)):
            new_eggs.append(self.frogs[i].lay_egg())
        with open("eggs.json", "w") as f:
            json.dump(new_eggs, f, indent=4, default=lambda x: x.__dict__)
        self.eggs = new_eggs
        print(f"saved {len(self.eggs)} eggs")
